2. Using Port Filters and Content-Based Routing
As stated in the
previous section, subscriptions and context properties are integral to
the messaging subsystem. Property schemas are the mechanism by which the
context properties or message data values are stored in the message
context. Besides the properties promoted by a developer, the BizTalk
Message Bus also automatically promotes system-level properties from the
system property namespaces, depending on the type of inbound and
outbound transports that are being used. Each adapter will stamp its
specific values into context properties that then become available to
subscribers to act upon.
Most people new to BizTalk
don't understand how messages are routed within the product or how to
use the property schemas to affect the subscription. Exercise 1 will show you how you can use the property promotion to implement routing logic.
Assume that there are three systems: a web site, a
POS application, and an automated FTP upload location. Each of these
locations takes a different schema and must map it to internal schema.
This mapped message then needs to be sent to the ERP system. However, as
an added piece of functionality, documents from the web site need to be
sent to a separate location as well, and documents from the POS system
need to be sent to a file system directory so they can be batch uploaded
at a later time. Figures 1 and 2 define the schema for the internal messages and a possible solution architecture.
The requirements for this
solution are quite common in most BizTalk projects, and most new BizTalk
architects design it incorrectly. Generally those unfamiliar with the
subscription nature of the Message Bus will tend to build an
orchestration that has logical ports directly bound to the physical
ports. The orchestration would then use Decide shapes to send the
message to the appropriate send port, which will then send the message
on its way. An even worse solution is to create three orchestrations,
each of which receives the inbound message directly from the receive
location, executes the map from within the orchestration, and then has a
static bound port that is bound to the send port from within the
orchestration. This problem requires only messaging to be solved. No
orchestrations should be created here since no business logic is needed.
Routing the message to the correct location is not business logic, and
as such, an orchestration is not the correct tool to use from the
BizTalk Server toolbox.
To implement the routing logic,
subscriptions need to be created that allow the inbound message, once it
has been mapped, to be sent to the correct port. Here, you create
filters based on the MessageType context property that allow the Messaging Engine to automatically forward any messages of type http://ABC.FulFillment.BizTalk.Schemas.OrderSchema#Order
to the adapter, which communicates with the ERP system. The filter of
the port will modify the subscription in the Messagebox accordingly. In
the filter properties of the ERPSendPort, the expression shown in Figure 3 will be present.
You still have not seen how
to solve the problem of differentiating messages that are received from
each of the three separate order-producing systems. Notice that the
internal schema definition includes an element that will allow you to
store that data should it be available, but there are two problems: how
you get the value in this element and how you route messages based on
it. For adding this value into the data document, you use the inbound
map defined on the receive port. All you need to do is create a map from
the external schema to the internal schema and assign a constant value
for the SourceSystem element.
To allow you to route on the SourceSystem
property, you need to create a property schema to define what
properties you want to store in the context and to allow the Messaging
Engine to promote the value from the data in your inbound document. To
do this, add a new item to the schema project: in the list of BizTalk
project items, choose Property Schema. Add an attribute to the schema
called SourceSystem, as shown in Figure 4.
Figure 5 shows the schema for the internal order property schema as viewed in the BizTalk schema editor.
The next step is to associate the custom property schema to the internal order schema. To do this, right-click the SourceSystem element in the internal order property schema, and choose Promotions => Show Promotions, as demonstrated in Figure 6. Next, click the Promoted Properties tab, and click the open folder icon.
Once you have chosen OrderPropertySchema, highlight the SourceSystem
element on the left, and click the Add>> button. This will add
the element to the list of promoted properties. Notice that since there
is only one property defined in the property schema, the editor
automatically associates this field with the SourceSystem property in the property schema, as shown in Figure 7.
Compile the project and deploy it to the Management Database. Once the
property schema's assembly is deployed to the Management Database, it
will automatically be available in the list of properties in a ports
filter. If you create a new send port and want to only send documents
from the web site, you can add its SourceSystem property as a filter, and this will automatically update the subscription, as shown in Figure 8.
Another important fact to note
is that in this situation, you need to create only one receive port with
three receive locations. You also need to create three maps and add
them each to the transforms on the port. The pipeline will examine the
inbound schema for each map and send the inbound document to the correct
map. If no port has a subscription for a matching inbound message type,
an error will occur, and the message will become suspended.